package utils

import (
	"eag_arch_layout/internal/model"
	"fmt"
	"github.com/go-kratos/kratos/v2/errors"
	"github.com/golang-jwt/jwt/v4"
)

// GenerateToken 生成token
func GenerateToken(jwtSecret string, mapClaims map[string]interface{}) (string, error) {
	// Create a new token object, specifying signing method and the claims
	// you would like it to contain.
	//token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
	//	"foo": "bar",
	//	"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
	//})
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims(mapClaims))
	// Sign and get the complete encoded token as a string using the secret
	tokenString, err := token.SignedString([]byte(jwtSecret))
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// ParsingToken 解析token
func ParsingToken(jwtSecret string, headTokenStr string) (jwt.MapClaims, error) {

	// Parse takes the token string and a function for looking up the key. The latter is especially
	// useful if you use multiple keys for your application.  The standard is to use 'kid' in the
	// head of the token to identify which key to use, but the parsed token (head and claims) is provided
	// to the callback, providing flexibility.
	token, err := jwt.Parse(headTokenStr, func(token *jwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
		return []byte(jwtSecret), nil
	})
	if err != nil {
		return nil, errors.New(500, model.TOKEN_ERROR, err.Error())
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok {
		//fmt.Println(claims["foo"], claims["nbf"])
		return claims, nil
	} else {
		//fmt.Println(err)
		return nil, err
	}
}
